package com.polidea.rxohosble2.sample.example3_discovery;


import com.polidea.rxohosble2.RxBleDeviceServices;
import com.polidea.rxohosble2.sample.ResourceTable;
import ohos.agp.components.*;
import ohos.bluetooth.ble.GattCharacteristic;
import ohos.bluetooth.ble.GattService;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class DiscoveryResultsAdapter  extends BaseItemProvider {

    public DiscoveryResultsAdapter(OnClickListener listener) {
        this.listener=listener;
    }
    static class AdapterItem {

        static final int SERVICE = 1;
        static final int CHARACTERISTIC = 2;
        final int type;
        final String description;
        final UUID uuid;

        AdapterItem(int type, String description, UUID uuid) {
            this.type = type;
            this.description = description;
            this.uuid = uuid;
        }
    }

    private final List<AdapterItem> data = new ArrayList<>();
    private OnAdapterItemClickListener onAdapterItemClickListener;
    interface OnAdapterItemClickListener {
        void onAdapterViewClick(Component component);
    }

    private final Component.ClickedListener onClickListener=new Component.ClickedListener(){

        @Override
        public void onClick(Component component) {
            if (onAdapterItemClickListener != null) {
                onAdapterItemClickListener.onAdapterViewClick(component);
            }
        }
    };

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        if (position >= 0 && position < data.size()){
            return data.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemComponentType(int position) {
        return ((AdapterItem)getItem(position)).type;
    }

    @Override
    public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
        int viewType = getItemComponentType(position);

        Component itemView;
        if (convertComponent==null || ((int)convertComponent.getTag()!=viewType)){
            final int layout = viewType == AdapterItem.SERVICE ? ResourceTable.Layout_item_discovery_service : ResourceTable.Layout_item_discovery_characteristic;
            itemView = LayoutScatter.getInstance(componentContainer.getContext()).parse(layout, componentContainer, false);
            itemView.setTag(viewType);
        }else {
            itemView=convertComponent;
        }
        Text text1= (Text) itemView.findComponentById(ResourceTable.Id_text1);
        Text text2= (Text) itemView.findComponentById(ResourceTable.Id_text2);

//        itemView.setClickedListener(onClickListener);

        final AdapterItem item = (AdapterItem)getItem(position);
        if (viewType == AdapterItem.SERVICE) {
            text1.setText(String.format("Service: %s", item.description));
        } else {
            text1.setText(String.format("Characteristic: %s", item.description));
        }
        text2.setText(item.uuid.toString());
        itemView.setClickedListener(component -> {
            if (this.listener!=null){
                listener.onClick(position);
            }
        });
        return itemView;
    }

    void setOnAdapterItemClickListener(OnAdapterItemClickListener onAdapterItemClickListener) {
        this.onAdapterItemClickListener = onAdapterItemClickListener;
    }

    void swapScanResult(RxBleDeviceServices services) {
        data.clear();

        for (GattService service : services.getBluetoothGattServices()) {
            // Add service
            data.add(new AdapterItem(AdapterItem.SERVICE, getServiceType(service), service.getUuid()));
            final List<GattCharacteristic> characteristics = service.getCharacteristics();

            for (GattCharacteristic characteristic : characteristics) {
                data.add(new AdapterItem(AdapterItem.CHARACTERISTIC, describeProperties(characteristic), characteristic.getUuid()));
            }
        }

        notifyDataChanged();
    }


    private String describeProperties(GattCharacteristic characteristic) {
        List<String> properties = new ArrayList<>();
        if (isCharacteristicReadable(characteristic)) properties.add("Read");
        if (isCharacteristicWriteable(characteristic)) properties.add("Write");
        if (isCharacteristicNotifiable(characteristic)) properties.add("Notify");
        return String.join(" ", properties);
    }

    private String getServiceType(GattService service) {
        return service.isPrimary()? "primary" : "secondary";
    }

    private boolean isCharacteristicNotifiable(GattCharacteristic characteristic) {
        return (characteristic.getProperties() & GattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0;//TODO：ERROR缺少通知属性 PROPERTY_NOTIFY，暂时设置为PROPERTY_WRITE_NO_RESPONSE
    }
    private boolean isCharacteristicReadable(GattCharacteristic characteristic) {
        return ((characteristic.getProperties() & GattCharacteristic.PROPERTY_READ) != 0);
    }

    private boolean isCharacteristicWriteable(GattCharacteristic characteristic) {
        return (characteristic.getProperties() & (GattCharacteristic.PROPERTY_WRITE
                | GattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) != 0;
    }


    OnClickListener listener;
    public interface OnClickListener{
        void onClick(int position);
    }


}